package com.zimi.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zimi.mapper.*;
import com.zimi.model.*;
import com.zimi.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 系统组织机构 Service
 *
 * @author lxc
 * @since 2019-07-16
 */
@Service
public class SysOrgLeaderService {
    @Autowired
    private SysOrgLeaderMapper sysOrgLeaderMapper;

    @Autowired
    private SysOrgMapper sysOrgMapper;

    @Autowired
    private SysPostMapper sysPostMapper;

    /*
     * 取得指定机构的领导岗位名称一览
     * */
    public List<SysOrgExtend> getLeaderPostNameByOrg(int orgId) {
        List<SysOrgExtend> result = new ArrayList<>();

        // 1)取出机构领导数据
        List<SysOrgLeader> list = sysOrgLeaderMapper.selectList(new LambdaQueryWrapper<SysOrgLeader>().eq(SysOrgLeader::getState, 1).eq(SysOrgLeader::getOriginOrgId, orgId).orderByAsc(SysOrgLeader::getLeaderSort));

        if (list != null && list.size() > 0) {
            List<Integer> orgIds = new ArrayList<>();
            Map<Integer, String> orgMap = new HashMap<>();

            List<Integer> postIds = new ArrayList<>();
            Map<Integer, String> postMap = new HashMap<>();
            String tmpPostName = null;

            // 2)默认岗位和岗位分离
            for (SysOrgLeader sol : list) {
                if (sol.getPostId() == 0) {
                    orgIds.add(sol.getOrgId());
                } else {
                    postIds.add(sol.getPostId());
                }
            }

            // 3)取得默认岗位名称
            if (orgIds.size() > 0) {
                List<SysOrg> orgList = sysOrgMapper.selectPostNameByOrgList(orgIds);

                if (orgList != null && orgList.size() > 0) {
                    for (SysOrg so : orgList) {
                        orgMap.put(so.getId(), String.format("%s-%s", so.getOrgName(), so.getPostName()));
                    }
                }
            }

            // 4)取得岗位名称
            if (postIds.size() > 0) {
                List<SysOrgExtend> postList = sysPostMapper.selectPostNameByPostIds(postIds);

                if (postList != null && postList.size() > 0) {
                    for (SysOrgExtend soe : postList) {
                        postMap.put(soe.getPostId(), String.format("%s-%s", soe.getOrgName(), soe.getPostName()));
                    }
                }
            }

            // 5)排序顺序取得名称
            for (SysOrgLeader sol : list) {
                SysOrgExtend tmpExtend = new SysOrgExtend();

                if (sol.getPostId() == 0) {
                    tmpPostName = orgMap.get(sol.getOrgId());
                } else {
                    tmpPostName = postMap.get(sol.getPostId());
                }

                if (tmpPostName != null) {
                    tmpExtend.setId(sol.getId());
                    tmpExtend.setOgnId(sol.getOriginOrgId());
                    tmpExtend.setOrgId(sol.getOrgId());
                    tmpExtend.setPostId(sol.getPostId());
                    tmpExtend.setPostName(tmpPostName);
                    tmpExtend.setState(sol.getState());
                    tmpExtend.setSort(sol.getLeaderSort());
                    tmpExtend.setUpdateTime(sol.getUpdateTime());

                    result.add(tmpExtend);
                }
            }
        }

        return result;
    }


    public void save(SysOrgLeader orgLeader) {

        Date dateTime = new Date();
        SysUser sysUser = UserUtil.getUser();

        int sort = 0;
        if (orgLeader.getId() == null) {
            List<SysOrgLeader> list = new SysOrgLeader().selectList(new LambdaQueryWrapper<SysOrgLeader>().eq(SysOrgLeader::getOriginOrgId, orgLeader.getOriginOrgId()).orderByDesc(SysOrgLeader::getLeaderSort));

            //根据不同的originOrgId来处理sort
            if (list != null && list.size() > 0) {
                //获取同originOrgId最大的sort
                sort = list.get(0).getLeaderSort();
                orgLeader.setLeaderSort(sort + 1);
            } else {
                orgLeader.setLeaderSort(sort + 1);
            }
            orgLeader.setCreateTime(dateTime);
            orgLeader.setCreateUser(sysUser.getId());

            orgLeader.insert();
        } else { //更新或删除
            // 1) 对修改对象进行行加锁
            SysOrgLeader rowData = new SysOrgLeader().selectOne(new LambdaQueryWrapper<SysOrgLeader>().eq(SysOrgLeader::getId, orgLeader.getId()).last("for update"));
            // 2)如果传过来的时间与行锁时间不同则抛出异常
            if (rowData.getUpdateTime() != null) { //确保是第二次修改才进入
                if (orgLeader.getUpdateTime().getTime() != rowData.getUpdateTime().getTime()) {
                    throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                }
            }

            // 3) 修改数据
            orgLeader.setUpdateTime(dateTime);
            orgLeader.setUpdateUser(sysUser.getId());

            orgLeader.updateById();
        }

    }

    /**
     * @desc 上移
     */

    @Transactional
    public void moveUp(SysOrgExtend orgExtend) {
        SysOrgLeader orgLeader = new SysOrgLeader().selectById(orgExtend.getId());
        List<SysOrgLeader> list = new SysOrgLeader().selectList(new LambdaQueryWrapper<SysOrgLeader>().eq(SysOrgLeader::getOriginOrgId, orgExtend.getOgnId()).eq(SysOrgLeader::getState, 1).orderByAsc(SysOrgLeader::getLeaderSort));

        if (list != null && list.size() > 0) {
            List<SysOrgLeader> tmpList = new ArrayList<>();

            for (SysOrgLeader sol : list) {
                if (sol.getLeaderSort() < orgExtend.getSort()) {
                    tmpList.add(sol);
                }
            }

            if (tmpList.size() == 0) {
                throw new RuntimeException("已经到达顶部!");
            } else {
                //1. 取出上一行
                SysOrgLeader upLeader = tmpList.get(tmpList.size() - 1);

                //2 取出上一行的sort和id
                int upSort = upLeader.getLeaderSort();
                int sort = orgExtend.getSort();
                int upId = upLeader.getId();
                int id = orgExtend.getId();

                //3 交换sort
                upLeader.setLeaderSort(sort);
                orgLeader.setLeaderSort(upSort);

                Map solMap = new HashMap();
                solMap.put(upId, upLeader);
                solMap.put(id, orgLeader);

                List<Integer> ids = new ArrayList<>();
                ids.add(upId);
                ids.add(id);

                //3 对要操作的两行添加行锁
                List<SysOrgLeader> rowData = sysOrgLeaderMapper.selectList(new QueryWrapper<SysOrgLeader>().lambda().in(SysOrgLeader::getId, ids).last("for update"));

                if (rowData == null || rowData.size() != 2) {
                    throw new RuntimeException("服务器关于交换顺序的数据异常。");
                }

                SysUser user = UserUtil.getUser();
                Date updateTime = new Date();

                for (SysOrgLeader sol : rowData) {

                    SysOrgLeader tmpSOL = (SysOrgLeader) solMap.get(sol.getId());
                    // 3）判断该数据已经被改过没有
                    if (sol.getUpdateTime() != null) {
                        if (tmpSOL.getUpdateTime() == null) {
                            throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                        } else {
                            if (sol.getUpdateTime().getTime() != tmpSOL.getUpdateTime().getTime()) {
                                throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                            }
                        }
                    }

                    // 4)变更数据

                    tmpSOL.setUpdateUser(user.getId());
                    tmpSOL.setUpdateTime(updateTime);
                    tmpSOL.updateById();
                }
            }
        }
    }

    /**
     * @author wh
     * @desc 下移
     */
    @Transactional
    public void moveDown(SysOrgExtend orgExtend) {
        SysOrgLeader orgLeader = new SysOrgLeader().selectById(orgExtend.getId());
        List<SysOrgLeader> list = new SysOrgLeader().selectList(new LambdaQueryWrapper<SysOrgLeader>().eq(SysOrgLeader::getOriginOrgId, orgExtend.getOgnId()).eq(SysOrgLeader::getState, 1).orderByAsc(SysOrgLeader::getLeaderSort));

        if (list != null && list.size() > 0) {
            List<SysOrgLeader> tmpList = new ArrayList<>();

            for (SysOrgLeader sol : list) {
                if (sol.getLeaderSort() > orgExtend.getSort()) {
                    tmpList.add(sol);
                }
            }

            if (tmpList.size() == 0) {
                throw new RuntimeException("已经到达底部!");
            } else {
                //1. 取出下一行
                SysOrgLeader downLeader = tmpList.get(0);

                //2 取出下一行的sort和id
                int upSort = downLeader.getLeaderSort();
                int sort = orgExtend.getSort();
                int upId = downLeader.getId();
                int id = orgExtend.getId();

                //3 交换sort
                downLeader.setLeaderSort(sort);
                orgLeader.setLeaderSort(upSort);

                Map solMap = new HashMap();
                solMap.put(upId, downLeader);
                solMap.put(id, orgLeader);

                List<Integer> ids = new ArrayList<>();
                ids.add(upId);
                ids.add(id);

                //3 对要操作的两行添加行锁
                List<SysOrgLeader> rowData = sysOrgLeaderMapper.selectList(new QueryWrapper<SysOrgLeader>().lambda().in(SysOrgLeader::getId, ids).last("for update"));

                if (rowData == null || rowData.size() != 2) {
                    throw new RuntimeException("服务器关于交换顺序的数据异常。");
                }

                SysUser user = UserUtil.getUser();
                Date updateTime = new Date();

                for (SysOrgLeader sol : rowData) {

                    SysOrgLeader tmpSOL = (SysOrgLeader) solMap.get(sol.getId());
                    // 3）判断该数据已经被改过没有
                    if (sol.getUpdateTime() != null) {
                        if (tmpSOL.getUpdateTime() == null) {
                            throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                        } else {
                            if (sol.getUpdateTime().getTime() != tmpSOL.getUpdateTime().getTime()) {
                                throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                            }
                        }
                    }

                    // 4)变更数据

                    tmpSOL.setUpdateUser(user.getId());
                    tmpSOL.setUpdateTime(updateTime);
                    tmpSOL.updateById();
                }
            }
        }
    }


}

